import json
import re
from loguru import logger


def load_json_file(file_path):
    import json
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    return data


def load_jsonl_file(file_path):
    import json
    with open(file_path, 'r', encoding='utf-8') as f:
        data = [json.loads(line) for line in f]
    return data


def fix_multiline_json_string(s: str) -> str:
    """
    修复包含字面换行的 JSON 字符串值。
    将字符串值内的实际换行替换为 \n，并去除多余空格。
    """
    # 匹配所有字符串值（包括跨行）
    def replace_match(match):
        # match.group(0) 是整个带引号的字符串，如 "xxx\n   yyy"
        content = match.group(1)  # 不带引号的内容
        # 将换行和后续空格替换为 \n（可选：压缩连续空格）
        content = re.sub(r"\s*\n\s*", r"\\n", content)
        return '"' + content + '"'

    # 匹配双引号字符串，支持跨行（非贪婪）
    fixed = re.sub(r'"((?:[^"\\]|\\.)*?)"', replace_match, s, flags=re.DOTALL)
    return fixed


def extract_all_json_from_output(output: str):
    """
    从大模型输出中提取所有被 ```json ... ``` 包裹的 JSON 内容，并解析为 Python 对象列表。
    """
    if output is None:
        return []
    # 匹配所有 ```json ... ``` 块（非贪婪、跨行）
    matches = re.findall(r"```json\s*(.*?)\s*```", output, re.DOTALL)

    results = []
    for json_str in matches:
        json_str = json_str.strip()
        json_str = fix_multiline_json_string(json_str)
        if not json_str:
            continue
        try:
            obj = json.loads(json_str)
            if isinstance(obj, list):
                results.extend(obj)
            else:
                results.append(obj)
        except json.JSONDecodeError:
            logger.error(f"Failed to parse JSON: {json_str}")
            continue
    return results


def strip_none_from_json(
    json_str: str, as_string: bool = True, ensure_ascii: bool = False
):
    """
    接受一个 JSON 格式的字符串，删除所有值为 None（JSON 中的 null）的键。
    返回值：
        - 如果 as_string 为 True，返回处理后的 JSON 字符串；
        - 否则返回处理后的 Python 对象（dict / list）。
    """
    if isinstance(json_str, str):
        data = json.loads(json_str)
    elif isinstance(json_str, (dict, list)):
        data = json_str
    cleaned = _remove_none_values(data)
    return json.dumps(cleaned, ensure_ascii=ensure_ascii) if as_string else cleaned


def _remove_none_values(obj):
    if isinstance(obj, dict):
        new = {}
        for k, v in obj.items():
            if v is None:
                continue
            elif v == "":
                continue
            new[k] = _remove_none_values(v)
        return new
    if isinstance(obj, list):
        return [_remove_none_values(i) for i in obj]
    return obj


def concat_all_values(data: dict, sep: str = "", skip_none: bool = True) -> str:
    """
    将传入 dict 中的所有 value 拼接成一个字符串。
    支持嵌套的 dict / list / tuple / set，非字符串值会被转换为 str。
    参数:
        - data: 要处理的 dict（也可传入 list/tuple/set）。
        - sep: 各个值之间的分隔符（默认无分隔）。
        - skip_none: 是否跳过 None 值（默认跳过）。
    返回:
        - 拼接后的字符串。
    """
    def _rec(obj):
        parts = []
        if obj is None:
            if skip_none:
                return []
            return ["None"]
        if isinstance(obj, dict):
            for v in obj.values():
                parts.extend(_rec(v))
            return parts
        if isinstance(obj, (list, tuple, set)):
            for v in obj:
                parts.extend(_rec(v))
            return parts
        # 原子值，转换为字符串
        return [str(obj)]

    all_parts = _rec(data)
    # 过滤空字符串以避免多余分隔
    all_parts = [p for p in all_parts if p != ""]
    return sep.join(all_parts)